package cn.ac.iie;

import net.sf.json.JSONArray;
import net.sf.json.JSONException;
import net.sf.json.JSONObject;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import sun.misc.BASE64Decoder;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @auther Fighter Created on 2016/11/14.
 */
public class TestJson {

    private static final Logger logger = Logger.getLogger(TestJson.class);
    public static String dirname, comID, data_type, fieldName;
    public static PrintWriter pw;

    static File[] fileList = null;
    static int fieldCount = 0;

    static boolean beStop = false;
    static boolean runningFlag = false;

    static InputWindow inputWindow = null;

    public static void showUsage() {
        System.out.println("java -jar jar包路径  dirname[目录名]  comID[企业名]  data_type[类型：要闻1，跟帖2，弹幕3，用户4]  fieldName[待查找字段]");
    }

    public static void main(String[] args) throws IOException {
        init(args);
//        getValues();
    }

    public static void init(String[] args) {

        PropertyConfigurator.configure(ClassLoader.getSystemClassLoader().getResource("log4j.properties"));

        try {
            Thread windowThread = new Thread() {
                @Override
                public void run() {
                    inputWindow = new InputWindow();
                }
            };

            windowThread.start();

           /* dirname = args[0];
            comID = args[1];
            data_type = args[2];
            fieldName = args[3];*/

            /*dirname = "G:\\iieproject\\jsonTest2";
            comID = "21";
            data_type = "1";
            fieldName = "LOCATIONINFO";*/

        } catch (Exception e) {
            showUsage();
            logger.error(e);
            System.exit(1);
        }

    }

    public static void getValues() throws Exception {

        TestJson.runningFlag = true;
        pw = new PrintWriter("G:\\iieproject\\TestJson\\src\\main\\resources\\info.log");
//        pw = new PrintWriter("./info.log");

        fileList = new File(dirname).listFiles();

        for (File file : fileList) {

//            pw.println("文件名：" + file.getName());
            System.out.println("文件名：" + file.getName());

            List<String> jsonStrList = Files.readAllLines(Paths.get(file.getAbsolutePath()));
            List<Map<String, String>> jsonData = null;

            for (int i = 0; i < jsonStrList.size(); i++) {

                String tmpJsonStr = jsonStrList.get(i);
//                String tmpJsonStr = jsonStrList.get(i).substring(14);
                String dataType = null;

                try {
                    //获取每条json字符串里的data_type
                    dataType = getType(tmpJsonStr);

                } catch (JSONException e) {
                    logger.error("json格式不对:" + "[文件名:" + file.getName() + "] [行号：" + (i + 1) + "]");
                    continue;
                }

                //选指定data_type的json字符串遍历
                if (data_type.equals(dataType)) {
                    try {

                        jsonData = getContentByRecord_list(tmpJsonStr, file, i);
                        for (int j = 0; j < jsonData.size(); j++) {

                            //遍历List里每一个map,每个map只有一个键值对{fieldName:value}
                            HashMap map = (HashMap) jsonData.get(j);
                            pw.println(String.join("-", dirname, comID, data_type, file.getName(), String.valueOf(i + 1), fieldName) + ":" + map.get(fieldName).toString());
                        }
                    } catch (Exception e) {
                        logger.error("[" + file.getName() + "] [" + (i + 1) + "] line parse error [" + e.getMessage() + "]");
                    }
                }
                tmpJsonStr = null;
            }
            jsonStrList = null;
//            pw.println("======================================================================================");
            if (beStop)
                break;

        }
        pw.close();
        System.out.println("遍历" + dirname + "内文件共：" + fileList.length + "个，共有指定字段" + fieldName + "：" + fieldCount + "个");
        TestJson.runningFlag = false;
    }

    /**
     * 改造后的函数 得到指定字段值
     *
     * @param jsonString json字符串
     * @param file       文件（打印日志用）
     * @param line       行号 （打印日志用）
     * @return 返回形如 [{filedName:value1},{fieldName:value2}...]
     */

    public static List<Map<String, String>> getContentByRecord_list(String jsonString, File file, int line) {

        JSONObject object = JSONObject.fromObject(jsonString);
//        HashMap<String, String> metaMap = getContentByRecord_meta(jsonString);

        List<Map<String, String>> mapList = new ArrayList<Map<String, String>>();
        JSONArray dataArray = object.getJSONArray("record_list");

        //遍历整个JSONArray
        for (int i = 0; i < dataArray.size(); i++) {

            JSONObject jsonObject = dataArray.getJSONObject(i);
            String tmpWEBSITEID = jsonObject.get("WEBSITEID").toString();

            //jsonObject中WEBSITEID是指定企业ID才取值
            if (comID.equals(tmpWEBSITEID)) {

                Map<String, String> map = new HashMap<>();
                String value = null;

                try {
                    value = jsonObject.get(fieldName).toString();
                } catch (JSONException je) {
                    continue;
                }

                value = processByRule(fieldName, value, file, line);

                ++fieldCount;
                map.put(fieldName, value);
                mapList.add(map);

            }
        }
        return mapList;
    }

    /**
     * 获取json字符串的
     *
     * @param jsonString
     * @return 返回json字符串里的data_type (e.g. 1,2,3,4)
     */

    public static String getType(String jsonString) {
        JSONObject jsonObject = JSONObject.fromObject(jsonString);
        return jsonObject.get("data_type").toString();
    }

    public static HashMap<String, String> getContentByRecord_meta(String jsonString) {

        JSONObject jo = JSONObject.fromObject(jsonString);
        JSONArray metaArray = jo.getJSONArray("record_meta");
        HashMap<String, String> hashMap = new HashMap<>();

        for (Object object : metaArray) {

            JSONObject jsonObject = (JSONObject) object;
            hashMap.put(jsonObject.getString("name").trim(), jsonObject.get("type").toString().trim());
        }

        return hashMap;
    }

    /**
     * 根据接入标准v1.6对需要解码的字段进行解码（注：此处没有写完整，比如只对新闻内strings类型且base64编码过的 PHOTOURLS/VIDEOURLS/EMOTION 解码，解码后多一个 逗号
     *
     * @param key    json中的key
     * @param srcVal 待解码的值
     * @param file   文件（打印日志用）
     * @param line   行号 （打印日志用）
     * @return 返回base64解码后的字符串值
     */

    private static String processByRule(String key, String srcVal, File file, int line) {

        String val = srcVal;
        BASE64Decoder decoder = new BASE64Decoder();

        if ("1".equals(data_type)) {

            switch (key) {

                case "ORIGINPAGE":
                case "TITLE":
                case "TEXT":
                case "AUTHOR":
                case "SPECIALNAME":
                case "MPAGESCREENSHOT":
                case "ORIGINURL":
                    try {
                        val = new String(decoder.decodeBuffer(srcVal));
                    } catch (IOException e) {
                        logger.error("解码失败!:" + "[文件名：" + file.getName() + ",行号：" + (line + 1) + ",字段名：" + key + "]", e);
                    }
                    break;

                case "PHOTOURLS":
                case "VIDEOURLS":
                case "EMOTION":
                    if (val.length() > 2 && val.startsWith("[") && val.endsWith("]")) {

                        val = "[";
                        //取出每个双引号之间的内容
                        Pattern pattern = Pattern.compile("\\\"(.*?)\\\"");
                        Matcher matcher = pattern.matcher(srcVal);

                        while (matcher.find()) {
                            try {
                                val += ("\"" + new String(decoder.decodeBuffer(matcher.group(1))) + "\"");
                            } catch (IOException e) {
                                logger.error("解码失败!:" + "[文件名：" + file.getName() + ",行号：" + (line + 1) + ",字段名：" + key + "]", e);
                            }
                            val += ",";//多一个,
                        }
                        val += "]";

                        //去掉最后逗号
                        int pos = val.lastIndexOf(",");
                        val = val.substring(0, pos) + val.substring(pos + 1);
                        break;
                    }
                    //处理LOCATIONINFO
                case "LOCATIONINFO":

                    break;
            }
        } else if ("2".equals(data_type)) {

            switch (key) {

                case "ORIGINURL":
                case "POSTCONT":
                case "USERNAME":
                    try {
                        val = new String(decoder.decodeBuffer(srcVal));
                    } catch (IOException e) {
                        logger.error("解码失败!:" + "[文件名：" + file.getName() + ",行号：" + (line + 1) + ",字段名：" + key + "]", e);
                    }
                    break;
            }
        } else if ("3".equals(data_type)) {
            switch (key) {

                case "ORIGINURL":
                case "DANMAKUCONT":
                case "USERNAME":
                    try {
                        val = new String(decoder.decodeBuffer(srcVal));
                    } catch (IOException e) {
                        logger.error("解码失败!:" + "[文件名：" + file.getName() + ",行号：" + (line + 1) + ",字段名：" + key + "]", e);
                    }
                    break;
            }

        } else if ("4".equals(data_type)) {
            switch (key) {
                case "USERNAME":
                    try {
                        val = new String(decoder.decodeBuffer(srcVal));
                    } catch (IOException e) {
                        logger.error("解码失败!:" + "[文件名：" + file.getName() + ",行号：" + (line + 1) + ",字段名：" + key + "]", e);
                    }
                    break;
            }
        } else {
            logger.error("data_type is not exists![文件名：" + file.getName() + ",行号：" + line);
        }

        return val;
    }

    public static void clearFlag() {

        TestJson.runningFlag = false;
        TestJson.fieldCount = 0;

        TestJson.dirname = null;
        TestJson.comID = null;
        TestJson.data_type = null;
        TestJson.fieldName = null;

    }
}
